#include "serial.h"
#include "Com.h"
#include "queue.h"


#define SERIAL_TX_QUEUELENGTH   200


/*************** GLOBAL VARIABLES ************/
xQueueHandle Serial_Tx_CharQueue;
static uint32 Serial_Tx_IniFlag = 0;
static uint32 Serial_TxFlag;



/* The UART interrupt handler. As this uses the ISR.s assembly interrupt
entry point the IPL setting in the following prototype has no effect. The
interrupt priority is set by the call to  ConfigIntUART2() in Serial_Tx_Ini(). */
void __attribute__( (interrupt(ipl0), vector(_UART2_VECTOR))) Serial_Tx_IntWrapper( void );


void Serial_Tx_Ini(void)
{
    Serial_Tx_CharQueue = xQueueCreate(SERIAL_TX_QUEUELENGTH, sizeof(uint8));

    Serial_TxFlag = 0;

    Serial_Tx_IniFlag = 1;
}

void Serial_Tx_MainFunction(void)
{
    if(Serial_Tx_IniFlag == 1)
    {
        Com_Message_t msg;

        while(xQueueReceive(Com_TxMessageQueue, &msg, 0 /*no blocking time*/))
        {
            uint8 i, notlen, crc, ch;

            notlen = ~(msg.len);

            (void)xQueueSend(Serial_Tx_CharQueue, &(msg.len), 0 /*no block time*/);
            (void)xQueueSend(Serial_Tx_CharQueue, &(notlen),  0 /*no block time*/);
            (void)xQueueSend(Serial_Tx_CharQueue, &(msg.id),  0 /*no block time*/);

            // CRC = id + sum(data)
            crc = msg.id;

            for(i=0; i<msg.len; i++)
            {
                crc = crc + msg.data[i];

                (void)xQueueSend(Serial_Tx_CharQueue, &(msg.data[i]), 0 /*no block time*/);
            }

            (void)xQueueSend(Serial_Tx_CharQueue, &(crc),  0 /*no block time*/);

            // we have now at leats some char to send.
            // trigger tx int haldler to send them
            if(Serial_TxFlag == 0)
            {
                Serial_TxFlag = 1;
                IFS1SET = _IFS1_U2TXIF_MASK;
            }
        }
    }
}



void Serial_Tx_IntHandler(void)
{
    static uint8 ch;

    /* Are any Tx interrupts pending? */
    if(IFS1bits.U2TXIF == 1)
    {
        // fill buffer until it is full
        while(!(U2STAbits.UTXBF))
        {
            if(xQueueReceiveFromISR(Serial_Tx_CharQueue, &ch, (signed portBASE_TYPE *)0) == pdTRUE)
            {
                /* Send the next character queued for Tx. */
                U2TXREG = ch;
            }
            else
            {
                /* Queue empty, nothing to send. */
                Serial_TxFlag = 0;
                break;
            }
        }

        IFS1CLR = _IFS1_U2TXIF_MASK;
    }

    /* If sending or receiving necessitates a context switch, then switch now. */
    // TODO: is thi necessary?
    // portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
}






